package com.test;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import org.ejml.simple.SimpleMatrix;

import com.iamk.util.GetData;

import weka.core.Instances;
import weka.core.converters.ArffLoader;

public class ProcessData {
	List<SimpleMatrix> mTrainData;
	List<SimpleMatrix> mTestData;
	int nFolds = 10;
	public ProcessData() {
		mTrainData = new ArrayList<SimpleMatrix>();
		mTestData = new ArrayList<SimpleMatrix>();
	}
	
	public void createCVSet(Instances mInstances){
		List<double[][]> mData = new ArrayList<double[][]>();
		mInstances.setClassIndex(mInstances.numAttributes() -1);
		int numClass = mInstances.numClasses();
		for(int i = 0; i < numClass; i++){
			int temp = i;
			mData.add(GetData.getData(mInstances, temp + 1));
		}
		int m = mData.get(0)[0].length;
		for(int k = 0; k < nFolds; k++){
			System.out.println("Folds: " + (k+1));
			// Create Train i
			double[][] dataTrainLabel0 = GetData.getSubMatrixInvert(mData.get(0), Math.round(mData.get(0).length/10), m, k*Math.round(mData.get(0).length/10));
			SimpleMatrix dataTrain = new SimpleMatrix(dataTrainLabel0);
			for(int i = 1; i < mData.size(); i++){
				System.out.println("L"+(i+1)+": " + mData.get(i).length );
				int n = Math.round(mData.get(i).length/10);
				double[][] dataLabeli = GetData.getSubMatrixInvert(mData.get(i), n, m, k*Math.round(mData.get(i).length/10));
				SimpleMatrix mB = new SimpleMatrix(dataLabeli);
				dataTrain = dataTrain.combine(dataTrain.numRows(), 0, mB);
			}
			mTrainData.add(dataTrain);
			// Create Test i
			double[][] dataTestLabel0 = GetData.getSubMatrix(mData.get(0), Math.round(mData.get(0).length/10), m, 0);
			SimpleMatrix dataTestk = new SimpleMatrix(dataTestLabel0);
			for(int i = 1; i < mData.size(); i++){
				int n = Math.round(mData.get(i).length/10);
				double[][] dataLabeli = GetData.getSubMatrix(mData.get(i), n, m, k*n);
				SimpleMatrix mB = new SimpleMatrix(dataLabeli);
				dataTestk = dataTestk.combine(dataTestk.numRows(), 0, mB);
			}
			mTestData.add(dataTestk);
		}
	}
	
	public static void main(String[] args) {
		ArffLoader loader = new ArffLoader();
		ProcessData mPD = new ProcessData();
		Instances mInstances = null;
		try {
			loader.setFile(new File("D:\\workspace-thesis\\IAMK\\features.arff"));
			mInstances = loader.getDataSet();
			mPD.createCVSet(mInstances);
			System.out.println(mInstances.numInstances());

			for(int i = 0; i < mPD.mTrainData.size(); i++){
				System.out.println(mPD.mTestData.get(i).numRows() + "//"+ mPD.mTrainData.get(i).numRows());
				File fileTrain = new File(System.getProperty("user.dir") + "\\PreData\\train_" + (i+1) + ".arff");
				BufferedWriter bw = new BufferedWriter(new FileWriter(fileTrain, false));
				bw.write("@RELATION feature-train"+(i+1)+"\n");
				for (int j = 0; j < 9; j++) {
					bw.write("@ATTRIBUTE f" + (j + 1) + "	REAL\n");
				}
				bw.write("@attribute class {1,2,3,5,6,8,9,10,11,12,13,14}\n");
				bw.write("@data\n");
				bw.write(matrixToString(mPD.mTrainData.get(i)));
				bw.close();
				
				File fileTest = new File(System.getProperty("user.dir") + "\\PreData\\test_" + (i+1) + ".arff");
				BufferedWriter bwTest = new BufferedWriter(new FileWriter(fileTest,	false));
				bwTest.write("@RELATION feature-test"+(i+1)+"\n");
				for (int j = 0; j < 9; j++) {
					bwTest.write("@ATTRIBUTE f" + (j + 1) + "	REAL\n");
				}
				bwTest.write("@attribute class {1,2,3,5,6,8,9,10,11,12,13,14}\n");
				bwTest.write("@data\n");
				bwTest.write(matrixToString(mPD.mTestData.get(i)));
				bwTest.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	static String matrixToString(SimpleMatrix m){
		String result = "";
		StringBuilder sb = new StringBuilder();
		DecimalFormat df = new DecimalFormat("##.######");
		for(int i = 0; i < m.numRows(); i++){
			for(int j = 0; j < m.numCols(); j++){
				if(j == (m.numCols()-1))
					sb.append(String.valueOf(df.format(m.get(i, j))));
				else
					sb.append(String.valueOf(df.format(m.get(i, j)))+",");
			}
			sb.append("\n");
		}
		result = sb.toString();
		return result;
	}
	
}
